package com.yihr.util;

import com.yihr.Rsa;
import com.yihr.bean.TokenRes;
import com.yihr.bean.User;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwt;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JwtUtil {

    // 采用自定义键值，避免 jjwt 处理错误
    public static final String NOTBEFORE = "nb";
    public static final String EXPIRED = "ex";
    public static final String OUTTIME = "ot";

    static PrivateKey privateKey;

    static {
        try {
            URL resource = JwtUtil.class.getClassLoader().getResource("/prikey.pem");
            privateKey = Rsa.getPrivateKey(new File(resource.toURI()).getAbsolutePath());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }



    static public String createJwt(User user) {
        Map<String, Object> payloads = new HashMap<>();
        payloads.put("uid", user.getId());
        payloads.put("sub", user.getUsername());
        payloads.put("email", user.getEmail());
        payloads.put("state", user.getState());

        payloads.put(NOTBEFORE, Instant.now().getEpochSecond());
        payloads.put(EXPIRED, Instant.now().plusSeconds(30L * 60).getEpochSecond());
        payloads.put(OUTTIME, Instant.now().plus(7, ChronoUnit.DAYS).getEpochSecond());


        if (StringUtil.isNotEmpty(user.getPhone())) {
            payloads.put("phone", user.getPhone());
        }
        if (null != user.getRoles() && user.getRoles().size()> 0) {
            payloads.put("role", user.getRoles());
        }

        String jwt = Jwts.builder()
                .setClaims(payloads)
                .signWith(SignatureAlgorithm.RS256, privateKey).compact();
        return jwt;
    }


    static public String freshJwtDT(Map<String, Object> payloads) {
        payloads.put(NOTBEFORE, Instant.now().getEpochSecond());
        payloads.put(EXPIRED, Instant.now().plusSeconds(30L * 60).getEpochSecond());
        payloads.put(OUTTIME, Instant.now().plus(7, ChronoUnit.DAYS).getEpochSecond());

        String jwt = Jwts.builder()
                .setClaims(payloads)
                .signWith(SignatureAlgorithm.RS256, privateKey).compact();
        return jwt;
    }

    public static TokenRes decodeToken(String token) {
        Jwt parse = Jwts.parser().setSigningKey(privateKey).parse(token);

        Map<String, Object> body = (Map<String, Object>) parse.getBody();

        Long nbf = Long.valueOf(body.get(NOTBEFORE).toString());
        Long exp = Long.valueOf(body.get(EXPIRED).toString());
        Long ot = Long.valueOf(body.get(OUTTIME).toString());

        System.out.println(parse.getHeader());
        System.out.println(parse.getBody());
        return new TokenRes(nbf, exp, ot, body);
    }


}
